package com.zuul.filter;

import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

/**
 * 	过滤器与拦截器
 * @author whxn520 2021年10月10日下午8:05:22
 */
@Component
public class AuthFilter extends ZuulFilter{

	private final static Logger LOGGER = LoggerFactory.getLogger(AuthFilter.class);
	
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    /** 排除过滤的uri地址  */
    // 登录
    private static final String LOGIN_URI = "login";

    /**
	 * 过滤器类型  属于前缀
	 */
	@Override
	public String filterType() {
		return FilterConstants.PRE_TYPE;
	}

	/**
	 * 过滤器顺序  数字越小越靠前
	 */
	@Override
	public int filterOrder() {
		return FilterConstants.SEND_ERROR_FILTER_ORDER;
	}

	
    /**
     * 	过滤器是否生效
     */
	@Override
	public boolean shouldFilter() {
		RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        List<String> uriArr = Arrays.asList(request.getRequestURI().split("/"));
        /**************** 无需拦截的接口配置 **************************/
        if (uriArr.contains(LOGIN_URI)) {
            return false;
        }
		return true;
	}

	/**
	 * token 认证
	 */
	@Override
	public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");
        // token 不存在拒绝请求
        if(StringUtils.isBlank(token)){
        	ctx.setSendZuulResponse(false);
        	ctx.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
        	ctx.setResponseBody("unAuthrized no token");
            return ctx;
        }
        try {
        	 String redisToken = stringRedisTemplate.opsForValue().get("token:"+token);
             // token值有问题拒绝请求
             if(StringUtils.isBlank(redisToken)){
             	ctx.setSendZuulResponse(false);
             	ctx.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
             	ctx.setResponseBody("token auth fail");
             	LOGGER.info("token认证失败 +: ");
                return ctx;
             }
             // 验证toke不一致
             if(!token.equals(redisToken.replace("\"", ""))){
             	ctx.setSendZuulResponse(false);
             	ctx.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
             	ctx.setResponseBody("token expired");
                return ctx;
             }
		} catch (Exception e) {
			LOGGER.error("获取redis中的toke服务异常:{}",e);
			ctx.setSendZuulResponse(false);
			ctx.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
			ctx.setResponseBody("token auth fail");
			return ctx;
		}
        return null;
	}

	
}
